﻿using System.Collections.ObjectModel;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
using WorkItem = VisualWip.Core.WorkItem;

namespace VisualWip.TFS2010Providers
{
    public class WorkItemTransformer
    {
        public static WorkItem TransformWorkItem(Microsoft.TeamFoundation.WorkItemTracking.Client.WorkItem workItem)
        {
            WorkItem newWorkItem = GetNewWorkItem(workItem);

            foreach (Field field in workItem.Fields)
            {
                newWorkItem.Fields.Add(field.Name, field.Value);
            }

            return newWorkItem;
        }

        private static WorkItem TransformWorkItem(Microsoft.TeamFoundation.WorkItemTracking.Client.WorkItem workItem,
                                                  DisplayFieldList displayFieldList)
        {
            WorkItem newWorkItem = GetNewWorkItem(workItem);

            foreach (FieldDefinition field in displayFieldList)
            {
                if (workItem.Fields.Contains(field.Name))
                    newWorkItem.Fields.Add(field.Name, workItem.Fields[field.Name].Value);
                else
                    newWorkItem.Fields.Add(field.Name, string.Empty);
            }

            return newWorkItem;
        }

        private static WorkItem GetNewWorkItem(Microsoft.TeamFoundation.WorkItemTracking.Client.WorkItem workItem)
        {
            var newWorkItem = new WorkItem();
            newWorkItem.Id = workItem.Id.ToString();
            newWorkItem.Title = workItem.Title;
            newWorkItem.TypeName = workItem.Type.Name;
            //newWorkItem.Description = workItem.Description;
            newWorkItem.State = workItem.State;
            return newWorkItem;
        }



        public static Collection<WorkItem> Transform(WorkItemCollection workItemCollection,
                                                     bool downloadDisplayFieldsOnly)
        {
            var result = new Collection<WorkItem>();
            foreach (Microsoft.TeamFoundation.WorkItemTracking.Client.WorkItem workItem in workItemCollection)
            {
                result.Add(GetWorkItem(downloadDisplayFieldsOnly, workItem, workItemCollection.DisplayFields));
            }

            return result;
        }

        public static Collection<WorkItem> BuildHierarchi(WorkItemLinkInfo[] links, WorkItemCollection workItems,
                                                          bool downloadDisplayFieldsOnly)
        {
            var result = new Collection<WorkItem>();

            for (int index = 0; index < links.Length; index++)
            {
                WorkItemLinkInfo workItemLinkInfo = links[index];
                int workItemsIndex = workItems.IndexOf(workItemLinkInfo.TargetId);

                if (!HasParent(workItemLinkInfo) && workItemsIndex >= 0)
                {
                    WorkItem transformWorkItem = GetWorkItem(downloadDisplayFieldsOnly, workItems[workItemsIndex],
                                                             workItems.DisplayFields);

                    result.Add(transformWorkItem);
                    AddChildren(links, index, workItems, transformWorkItem, downloadDisplayFieldsOnly);
                }
            }

            return result;
        }

        private static void AddChildren(WorkItemLinkInfo[] links, int index, WorkItemCollection workItems,
                                        WorkItem parentWorkItem, bool downloadDisplayFieldsOnly)
        {
            int myIndex = index + 1;

            while (myIndex < links.Length && HasParent(links[myIndex]))
            {
                WorkItemLinkInfo workItemLinkInfo = links[myIndex];
                int workItemsIndex = workItems.IndexOf(workItemLinkInfo.TargetId);

                if (MatchingParent(workItemLinkInfo, parentWorkItem) && workItemsIndex >= 0)
                {
                    WorkItem childWorkItem = GetWorkItem(downloadDisplayFieldsOnly, workItems[workItemsIndex],
                                                         workItems.DisplayFields);
                    parentWorkItem.Children.Add(childWorkItem);
                    AddChildren(links, myIndex, workItems, childWorkItem, downloadDisplayFieldsOnly);
                }
                myIndex++;
            }
        }

        private static WorkItem GetWorkItem(bool downloadDisplayFieldsOnly,
                                            Microsoft.TeamFoundation.WorkItemTracking.Client.WorkItem workItem,
                                            DisplayFieldList displayFieldList)
        {
            return downloadDisplayFieldsOnly ? TransformWorkItem(workItem, displayFieldList) : TransformWorkItem(workItem);
        }

        private static bool MatchingParent(WorkItemLinkInfo childLinkInfo, WorkItem parentWorkItem)
        {
            return childLinkInfo.SourceId.ToString() == parentWorkItem.Id;
        }

        private static bool HasParent(WorkItemLinkInfo workItemLinkInfo)
        {
            return workItemLinkInfo.SourceId > 0;
        }
    }
}